﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SharpMUSH
{
    public enum OptionCategory
    {
        NONE,
        ESSENTIALS,
        LIMITS,
        DUMP,
        FILENAMES,
        LOGGING,
        LOGINS,
        COMMANDS,
        ATTRIBUTES,
        COSMETIC,
        FLAGS
    }

    public class Option
    {
        public string Name;     // Name of Option
        public string[] Values; // Values/Settings
        public Perm Write =  Perm.GOD;    // Who can modify this option
        public Perm Read = Perm.WIZARD;     // Who can see this option
        public OptionCategory Category = OptionCategory.NONE;
        
        /// <summary>
        /// Create a new Option
        /// </summary>
        /// <param name="line">String from mush.cnf</param>
        public Option(string line, bool noDefault = false)
        {
            ParseLine(line, noDefault);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="line">String from mush.cnf</param>
        /// <param name="cat">Category</param>
        public Option(string line, OptionCategory cat, bool noDefault = false)
        {
            ParseLine(line, noDefault);
            Category = cat;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="line">String from mush.cnf</param>
        /// <param name="read">Who can read</param>
        /// <param name="write">Who can write</param>
        public Option(string line, Perm read, Perm write, bool noDefault = false)
        {
            ParseLine(line, noDefault);
            Read = read;
            Write = write;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="line">String from mush.cnf</param>
        /// <param name="read">Who can read</param>
        /// <param name="write">Who can write</param>
        /// <param name="cat">Category</param>
        public Option(string line, Perm read, Perm write, OptionCategory cat, bool noDefault = false)
        {
            ParseLine(line, noDefault);
            Read = read;
            Write = write;
            Category = cat;
        }

        /// <summary>
        /// Parse through a string from the mush.cnf and seperate out command and arguments
        /// </summary>
        /// <param name="line">Line from mush.cnf</param>
        private void ParseLine(string line, bool noDefault)
        {
            string[] args = line.Trim().Replace(Environment.NewLine, "").Split(' ');
            Name = args[0].ToLower();
            if (args.Length > 1)
            {
                Values = new string[args.Length - 1];

                for (int i = 1; i < args.Length; i++)
                {
                    Values[i - 1] = args[i];
                }
            }
            else
            {

                // Nothing supplied we should get the default here,
                if (Config.Defaults != null || noDefault == false)
                {
                    Option def = null;
                    foreach (Option opt in Config.Defaults)
                    {
                        if (opt.Name == Name)
                        {
                            def = opt;
                        }
                    }

                    if (def != null)
                    {
                        string[] dValues = def.Values;
                        Values = dValues;
                    }
                }
                else
                {
                    Values = new string[] { "" };
                }
            }

        }

        /// <summary>
        /// Get a string version of the arguments supplied.
        /// </summary>
        /// <returns>String</returns>
        public string GetString()
        {
            string result = string.Empty;

            foreach (string arg in Values)
            {
                result += arg + " ";
            }
            return result.Trim();

        }

        /// <summary>
        /// Returns a string with safe directory seperators
        /// </summary>
        /// <returns>String</returns>
        public string GetPath()
        {
            return Convert.SafePath(GetString());
        }

        public bool GetBool()
        {
            switch (Values[0])
            {
                case "1":
                case "true":
                case "on":
                    return true;
                case "0":
                case "false":
                case "off":
                    return false;
                default:
                    // Return default value
                    return false;
            }
        }

        /// <summary>
        /// Get an integer version of value
        /// </summary>
        /// <returns>Int32</returns>
        public int GetInt()
        {
            int result;
            try
            {
                result = Int32.Parse(Values[0]);
            }
            catch
            {
                Console.WriteLine("{0} has an invalid option - using default!");
                result = 0;
            }
            return result;
        }

        /// <summary>
        /// Get a TimeSpan version of value.
        /// </summary>
        /// <returns>TimeSpan</returns>
        public TimeSpan GetTime()
        {
            TimeSpan result;


            int seconds = 0;
            int minutes = 0;
            int hours = 0;
            int days = 0;


            string temp = Values[0];
            if (temp.Contains("d"))
            {
                string[] s = temp.Split('d');
                Int32.TryParse(s[0], out days);
                temp = s[1];
            }

            if (temp.Contains("h"))
            {
                string[] s = temp.Split('h');
                Int32.TryParse(s[0], out hours);
                temp = s[1];
            }

            if (temp.Contains("m"))
            {
                string[] s = temp.Split('m');
                Int32.TryParse(s[0], out minutes);
                temp = s[1];
            }

            if (temp.Contains("s"))
            {
                string[] s = temp.Split('s');
                Int32.TryParse(s[0], out seconds);
            }

            if (seconds >= 60)
            {
                int t = (seconds / 60);
                minutes += t;
                seconds -= t * 60;
            }

            if (minutes >= 60)
            {
                int t = minutes / 60;
                hours += t;
                minutes -= t * 60;
            }

            if (hours >= 24)
            {
                int t = hours / 24;
                days += t;
                hours -= t * 24;
            }

            result = new TimeSpan(days, hours, minutes, seconds);
            return result;
        }
    }
}
